package com.gxuwz.stats.controller;

import com.gxuwz.stats.entity.User;
import com.gxuwz.stats.security.jwt.JwtTokenUtil;
import com.gxuwz.stats.service.JwtUserDetailsService;
import com.gxuwz.stats.service.LoginService;
import com.gxuwz.stats.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/auth")
public class LoginController {

    @Autowired
    private LoginService loginService;
    @Autowired
    private UserService userService;
    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtUserDetailsService userDetailsService;

    //测试
    @PostMapping("/login")
    public ResponseEntity<Map<String, Object>> login(@RequestBody User loginRequest, HttpSession session) {
        System.out.println(session);
        System.out.println("Frontend verifyCode: " + loginRequest.getCode()); // 打印前端传递的验证码

        // 获取 uuid 和 code
        String uuid = loginRequest.getUuid();
        String code = loginRequest.getCode();

        // 从 session 取出验证码 map
        Map<String, String> captchaMap = (Map<String, String>) session.getAttribute("captchaMap");
        if (captchaMap == null || !captchaMap.containsKey(uuid)) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 400);
            errorResponse.put("message", "验证码已过期或无效，请重新点击验证码进行刷新！");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
        }
        String realCode = captchaMap.get(uuid);
        if (!realCode.equalsIgnoreCase(code)) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 400);
            errorResponse.put("message", "验证码错误！");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
        }
        // 校验通过后，移除该 uuid，防止复用
        captchaMap.remove(uuid);
        session.setAttribute("captchaMap", captchaMap);

        // 用户名和密码验证逻辑
        User user = loginService.getByNameAndPassword(loginRequest.getUserId(), loginRequest.getPassword());
        if (user == null) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 400);
            errorResponse.put("message", "用户名或密码错误！");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
        }

        // 获取用户角色
        String userRole = loginService.getUserRoleByName(user.getUsername());
        System.out.println("角色="+userRole);
// 创建 UserDetails 对象
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"))
        );
//        SecurityContextHolder.getContext().setAuthentication(authentication);
        // 创建 Authentication 对象并存储到 SecurityContext
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                userDetails, // 使用 UserDetails 对象作为 Principal
                null,
                userDetails.getAuthorities()
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String userId = user.getUserId();
        String department = user.getDepartment();
//        String role = user.getRole();
//        System.out.println("1241322132="+userId);
        // 生成 JWT Token
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        String token = jwtTokenUtil.generateToken(userDetails, userId,department,userRole);

        // 登录成功后
        boolean firstLogin = user.getFirstLogin();
        // 创建响应数据
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("code", 200);
        responseData.put("msg", "登录成功");
        Map<String, Object> data = new HashMap<>();
        data.put("role", userRole);
        data.put("firstLogin", firstLogin);
        data.put("token", token);
        data.put("userId", user.getUserId()); // 明确返回userId
        data.put("username", user.getUsername());
        responseData.put("data", data);

        // 存储用户信息到 Session
        session.setAttribute("user", user);

        return ResponseEntity.ok(responseData);
    }

//    @GetMapping("/verify-code")
//    public ResponseEntity<Map<String, Object>> getVerifyCode(HttpSession session) throws IOException {
//        VerifyCode code = new VerifyCode();
//        BufferedImage image = code.createImage();
//        // 获取验证码文本
//        String verifyCodeText = code.getText();
//        System.err.println("Generated verify code: " + verifyCodeText);
//
//        // 将验证码文本存储到 Session 中
//        session.setAttribute("verifyCode", verifyCodeText);
//
//        // 构建响应体，包含验证码图片数据
//        Map<String, Object> responseBody = new HashMap<>();
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        ImageIO.write(image, "jpg", baos);
//        byte[] imageBytes = baos.toByteArray();
//        responseBody.put("image", Base64.getEncoder().encodeToString(imageBytes));
//
//        return ResponseEntity.ok(responseBody);
//    }

    /**
     * 退出功能
     * @param authorization
     * @return
     */
    @PostMapping("/logout")
    public ResponseEntity<?> logout(@RequestHeader("Authorization") String authorization) {
        if (authorization != null && authorization.startsWith("Bearer ")) {
            // 提取 Token
            String token = authorization.replace("Bearer ", "");

            logger.info("Received logout request with token: {}", token);

            Map<String, Object> responseData = new HashMap<>();
            responseData.put("code", 200);
            responseData.put("msg", "Logout successful");
            return ResponseEntity.ok(responseData);
        } else {
            logger.warn("Logout attempted without valid token");
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("code", 400);
            responseData.put("msg", "Unauthorized");
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(responseData);
        }
    }

    /**
     * 获取到当前登录的用户
     * @param authentication
     * @return
     */
    @GetMapping("/current")
    public ResponseEntity<Map<String, Object>> getCurrentUser(Authentication authentication) {
//        System.out.println("11111="+authentication);
        if (authentication == null || !authentication.isAuthenticated()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }

        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
//        System.out.println("当前登录："+userDetails);

        String username = userDetails.getUsername();
        String userId = userService.getUserIdByUsername(username);
        Map<String, Object> response = new HashMap<>();
        response.put("userId", userId);
        response.put("username", userDetails.getUsername());
        response.put("code", 200);
//        response.put("password", userDetails.getPassword());
        return ResponseEntity.ok(response);
    }

    /**
     * 刷新Token
     * @param tokenRequest
     * @return
     */
    @PostMapping("/refresh")
    public ResponseEntity<?> refreshToken(@RequestBody Map<String, String> tokenRequest) {
        String refreshToken = tokenRequest.get("refreshToken");

        try {
            // 验证 refreshToken 有效性
            String username = jwtTokenUtil.getUsernameFromToken(refreshToken);
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);

            if (!jwtTokenUtil.validateToken(refreshToken, userDetails)) {
                throw new Exception("Invalid refresh token");
            }

            // 生成新的 accessToken
            String newAccessToken = jwtTokenUtil.refreshToken(refreshToken);

            // 使用兼容Java 8的写法
            Map<String, String> response = new HashMap<>();
            response.put("accessToken", newAccessToken);
            response.put("refreshToken", refreshToken);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid refresh token");
        }
    }

    /**
     * 首次登录修改密码
     * 前端发送请求，后端接收请求，修改密码，设置 first_login = false
     * @param req
     * @return
     */
    @PostMapping("/changePassword")
    public ResponseEntity<?> changePassword(@RequestBody Map<String, String> req) {
        String userId = req.get("userId");
        String newPassword = req.get("newPassword");

        // 1. 加密新密码
        String encodedPassword = new BCryptPasswordEncoder().encode(newPassword);

        // 2. 修改密码
        userService.updatePassword(userId, encodedPassword);

        // 3. 设置 first_login = false
        userService.updateFirstLogin(userId, false);

        Map<String, Object> resp = new HashMap<>();
        resp.put("code", 200);
        resp.put("msg", "密码修改成功");
        return ResponseEntity.ok(resp);
    }

}

